package com.rs.game.grandexchange;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import com.rs.cache.loaders.ItemDefinitions;
import com.rs.game.World;
import com.rs.game.grandexchange.GrandExchange.GrandExchangeType;
import com.rs.game.player.Player;
import com.rs.tools.FileManager;
import com.rs.utils.Logger;
import com.rs.utils.SerializableFilesManager;

public class GrandExchangeDatabase {
	public static final String PATH = "data/grandexchange/";
	
	public static HashMap<String, OfferSet> offers; //make a sign that displays these

	public static void init() {
		offers = new HashMap<String, OfferSet>();
		
		File file = new File(PATH);
		if (!file.exists()) {
			file.mkdirs();
		}
		int amount = 0;
		for (File offer : file.listFiles()) {
			try {
				OfferSet offerSet = (OfferSet) SerializableFilesManager.loadSerializedFile(offer);
				if (offerSet != null) {
					offers.put(offerSet.owner, offerSet);
				} else {
					FileManager.logError("Error loading GE offer: "+offer.getName());
				}
			} catch (Throwable e) {
				Logger.handle(e);
			}
		}
		System.out.println("Loaded "+amount+" grand exchange offers..");
	}

	public static final void save(Player player) {
		if (player == null)
			return;
		try {
			SerializableFilesManager.storeSerializableClass(player.getOfferSet(), new File(PATH+player.getUsername()+".ge"));
		} catch (Throwable e) {
			Logger.handle(e);
		}
	}
	
	public static final void save(String username, OfferSet offerSet) {
		try {
			SerializableFilesManager.storeSerializableClass(offerSet, new File(PATH+username+".ge"));
		} catch (Throwable e) {
			Logger.handle(e);
		}
	}
	
	public static OfferSet getOfferSet(Player player) {
		File file = new File(PATH+player.getUsername()+".ge");
		if (!file.exists()) {
			return new OfferSet(player.getUsername());
		} else {
			try {
				return (OfferSet) SerializableFilesManager.loadSerializedFile(file);
			} catch (ClassNotFoundException | IOException e) {
				FileManager.logError("Error loading GE file for "+player.getUsername());
			}
		}
		return null;
	}
	
	public static void processOffers() {
		ArrayList<Offer> buyOffers = new ArrayList<Offer>();
		ArrayList<Offer> sellOffers = new ArrayList<Offer>();
		
		for (OfferSet offerSet : offers.values()) {
			if (offerSet == null)
				continue;
			for (Offer offer : offerSet.offers) {
				if (offer == null)
					continue;
				if (offer.getAmountLeft() > 0) {
					if (offer.getCurrentType() == GrandExchangeType.BUYING) {
						buyOffers.add(offer);
					} else if (offer.getCurrentType() == GrandExchangeType.SELLING) {
						sellOffers.add(offer);
					}
				}
			}
		}
		
		for (Offer buyOffer : buyOffers) {
			for (Offer sellOffer : sellOffers) {
				if (buyOffer.getItemId() != sellOffer.getItemId())
					continue;
				if (buyOffer.getPricePerItem() < sellOffer.getPricePerItem())
					continue;
				
				int numberToTransact;
				if (buyOffer.getAmountLeft() >= sellOffer.getAmountLeft()) {
					numberToTransact = sellOffer.getAmountLeft();
				} else {
					numberToTransact = buyOffer.getAmountLeft();
				}
				
				int finalPrice = sellOffer.getPricePerItem();
				if (sellOffer.getPricePerItem() != buyOffer.getPricePerItem()) {
					finalPrice = (sellOffer.getPricePerItem()+buyOffer.getPricePerItem())/2;
				}
				int change = Math.abs(buyOffer.getPricePerItem()-finalPrice);
				
				buyOffer.transactBuy(numberToTransact, finalPrice, change);
				sellOffer.transactSell(numberToTransact, finalPrice);
				
				updateOffer(buyOffer);
				updateOffer(sellOffer);
				FileManager.writeToFile("GELog.txt", ""+buyOffer.getOwner()+": Bought "+numberToTransact+" "+ItemDefinitions.getItemDefinitions(buyOffer.getItemId())+" from "+sellOffer.getOwner());
			}
		}
	}
	
	public static void updateOffer(Offer offer) {
		Player player = World.getPlayer(offer.getOwner());
		OfferSet offerSet = offers.get(offer.getOwner());
		offerSet.offers[offer.getBox()] = offer;
		updateOfferSet(offer.getOwner(), offerSet, player != null);
	}
	
	public static void updateOfferSet(String username, OfferSet offerSet, boolean playerOn) {
		Player player = World.getPlayer(username);
		offers.remove(username);
		offers.put(username, offerSet);
		
		if (player != null && player.getUsername() != null) {
			for (int i = 0;i < offerSet.offers.length;i++) {
				Offer offer = offerSet.offers[i];
				player.setGrandExchangeOffer(offer, i);
			}
			player.getPackets().sendGameMessage("One or more of your grand exchange offers has been updated.");
			GrandExchange.updateGrandExchangeBoxes(player);
			save(player);
		} else {
			save(username, offerSet);
		}
		
	}
}
